﻿#region Using Statements
using System.Collections.Generic;
using GameBase.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace StarFox.Graphics
{
    /// <summary>
    /// Performs the last stage of processing before all Screen content is finally displayed.
    /// </summary>
    public class DisplayProcessor
    {
        #region Fields

        Effect effect;
        EffectParameter brightness;
        EffectParameter contrast;
        EffectParameter alpha;

        GraphicsDevice GraphicsDevice;
        QuadRenderer quad;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the brightness level of the image displayed.
        /// </summary>
        public int Brightness { get; set; }

        // relationship between menu values and brightness values
        Dictionary<int, float> brtList = new Dictionary<int, float>()
        {
            {0, -0.25f}, {1, -0.20f}, {2, -0.15f}, {3, -0.1f}, {4, -0.05f}, {5, 0.0f}, {6, 0.025f}, {7, 0.050f}, {8, 0.075f}, {9, 0.10f}, {10, 0.125f}
        };

        /// <summary>
        /// Gets or sets the contrast level of the image displayed.
        /// </summary>
        public int Contrast { get; set; }

        // relationship between menu values and contrast values
        Dictionary<int, float> crtList = new Dictionary<int, float>()
        {
            {0, 0.75f}, {1, 0.80f}, {2, 0.85f}, {3, 0.90f}, {4, 0.95f}, {5, 1.0f}, {6, 1.05f}, {7, 1.10f}, {8, 1.15f}, {9, 1.20f}, {10, 1.25f}
        };

        /// <summary>
        /// Gets or sets the transparency level of the image displayed.
        /// </summary>
        public float Alpha { get; set; }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of this class.
        /// </summary>
        /// <param name="effect">The display processing effect.</param>
        public DisplayProcessor(Effect effect)
        {
            this.effect = effect;
            GraphicsDevice = effect.GraphicsDevice;
            quad = new QuadRenderer(GraphicsDevice);

            brightness = effect.Parameters["Brightness"];
            contrast = effect.Parameters["Contrast"];
            alpha = effect.Parameters["Alpha"];

            Vector2 pixelSize = new Vector2(1.0f / (float)GraphicsDevice.PresentationParameters.BackBufferWidth,
                                            1.0f / (float)GraphicsDevice.PresentationParameters.BackBufferHeight);

            effect.Parameters["HalfPixelOffset"].SetValue(pixelSize * 0.5f);
        }

        #endregion

        #region Apply

        /// <summary>
        /// Applies the display processing effect.
        /// </summary>
        /// <param name="inTexture">Texture2D used as processing input.</param>
        /// <param name="outRenderTarget">RenderTarget2D used as processing output.</param>
        public void Apply(Texture2D inTexture, RenderTarget2D outRenderTarget)
        {
            brightness.SetValue(brtList[Brightness]);
            contrast.SetValue(crtList[Contrast]);
            alpha.SetValue(Alpha);

            GraphicsDevice.SetRenderTarget(outRenderTarget);
            GraphicsDevice.BlendState = BlendState.Additive;
            GraphicsDevice.DepthStencilState = DepthStencilState.None;
            GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
            GraphicsDevice.Clear(Color.Transparent);

            effect.Parameters["ScreenMap"].SetValue(inTexture);
            effect.CurrentTechnique.Passes[0].Apply();
            quad.Draw();
        }

        #endregion
    }
}
